﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using YaAppoint.Departments;
using YaAppoint.Response;

namespace YaAppoint
{
    [RemoteService(isEnabled: false)]
    public class DepartmentAppService(IRepository<Department, Guid> departmentRepository,
                                      IMapper mapper,
                                      IAsyncQueryableExecuter queryableExcuter) : ApplicationService, IDepartmentAppService,ITransientDependency
    {
        private readonly IRepository<Department, Guid> _departmentRepository = departmentRepository;
        private readonly IMapper _mapper= mapper;
        private readonly IAsyncQueryableExecuter _queryableExcuter = queryableExcuter;

        /// <summary>
        /// 获取单个
        /// </summary>
        public async Task<DepartmentDto> GetAsync(Guid id)
        {
            return _mapper.Map<Department,DepartmentDto>(await _departmentRepository.GetAsync(id)) ;
        }

        /// <summary>
        /// 删除
        /// </summary>
        public async Task<bool> Delete(Guid id)
        {
            var dep = await _departmentRepository.FirstOrDefaultAsync(d => d.Id == id);
            if (dep != null)
            {
                if (dep.Users!=null && dep.Users.Count > 0)
                {
                    dep.Users.Clear();
                }
                await _departmentRepository.DeleteAsync(id);
                return true;
            }
            return true;
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        public async Task<List<DepartmentDto>> GetListAsync(string? filterName)
        {
            var query = await _departmentRepository.GetQueryableAsync();
            if(!string.IsNullOrEmpty(filterName))
            {
                query = query.Where(x => x.Name.Contains(filterName));
            }
            query = query.OrderByDescending(x => x.Order);
            return  _mapper.Map<List<Department>, List<DepartmentDto>>(await _queryableExcuter.ToListAsync(query));
        }

        /// <summary>
        /// 新建
        /// </summary>
        public async Task<BackJson> CreateAsync(DepartmentCreateDto dto)
        {
            await ValidateCreateDto(dto);
            var dep = _mapper.Map<DepartmentCreateDto, Department>(dto);
            await _departmentRepository.InsertAsync(dep);
            var res = new BackJson()
            {
                code = 0,
                msg = "科室创建成功！"
            };
            return res;
        }

        /// <summary>
        /// 验证编码和外码是否已存在
        /// </summary>
        public async Task<bool> ValidateCreateDto(DepartmentCreateDto dto)
        {
            var list = await _departmentRepository.GetListAsync();
            if (list.Where(x => x.Code.Contains(dto.Code)).Count()>0)
            {
                throw new BusinessException(CustomErrorCodes.CodeAlreadyExist)
                {
                    Data =
                    {
                        { "code",dto.Code}
                    }
                };
            }
            if (list.Where(x=>x.OuterCode.Contains(dto.OuterCode)).Count()>0)
            {
                throw new BusinessException(CustomErrorCodes.OuterCodeAlreadyExist)
                {
                    Data =
                    {
                        { "outerCode",dto.OuterCode}
                    }
                };
            }
            return true;
        }

        /// <summary>
        /// 更新
        /// </summary>
        public async Task<BackJson> UpdateAsync(DepartmentDto dto)
        { 
            var dep = await _departmentRepository.GetAsync(dto.Id);
            if (dep == null)
            {
                throw new BusinessException(CustomErrorCodes.DepartmentNotExist);
            }
            dep.Name = dto.Name;
            dep.Order = dto.Order;
            dep.Code = dto.Code;
            dep.OuterCode = dto.OuterCode;
            dep.IsActive = dto.IsActive;
            dep.ContactPerson = dto.ContactPerson;
            dep.PhoneNumber = dto.PhoneNumber;
            dep.Desc = dto.Desc;
            await _departmentRepository.UpdateAsync(dep);

            return new BackJson()
            {
                code = 0,
                msg="保存成功。"
            };
        }
    }
}
